package com.cloudlead.plugin.security.service.impl;

import com.cloudlead.common.lang.security.SecurityUtils;
import com.cloudlead.common.persistence.QueryDslRepository;
import com.cloudlead.common.persistence.bean.BeanConvertUtils;
import com.cloudlead.plugin.security.query.*;
import com.cloudlead.plugin.security.service.ScResourceService;

import com.cloudlead.plugin.security.BusinessModules;
import com.cloudlead.plugin.security.service.ScUserService;
import com.cloudlead.plugin.security.vo.ScResource;
import com.cloudlead.plugin.security.entity.EScResource;
import com.cloudlead.plugin.security.vo.dict.PrivilegeCategory;
import com.mysema.query.BooleanBuilder;
import com.mysema.query.Tuple;
import com.mysema.query.sql.SQLQuery;
import com.mysema.query.types.OrderSpecifier;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import com.cloudlead.plugin.security.repository.EScResourceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import com.cloudlead.common.lang.annotation.Label;
import com.cloudlead.common.persistence.impl.AbstractMultiTableCrudService;

import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;

/**
 * ScResourceServiceImpl is a Codegen service implement type
 */
@Label("资源服务实现")
@Service("scResourceService")
public class ScResourceServiceImpl extends AbstractMultiTableCrudService<EScResourceRepository, ScResource, EScResource> implements ScResourceService {
    @Inject
    private ScUserService scUserService;

    @Autowired
    public ScResourceServiceImpl(EScResourceRepository eScResourceRepository) {
        super(BusinessModules.ScResource, eScResourceRepository);
    }


    @Override
    public List<ScResource> findResources(String username, Integer resourceCategory, List<PrivilegeCategory> privilegeCategories) {
        final List<String> privileges;
        if (username.equals(SecurityUtils.getUsername()) && null != SecurityUtils.getSubject()) {
            privileges = SecurityUtils.getSubject().getPrivileges();
        } else {
            privileges = scUserService.findPrivileges(username, null);
        }
        return repository.find(new QueryDslRepository.Query() {
            @Override
            public List<ScResource> queryInTransactional(SQLQuery sqlQuery) {
                BooleanBuilder booleanBuilder = new BooleanBuilder();
                if (null != resourceCategory) {
                    booleanBuilder.and(QScResource.scResource.category.eq(resourceCategory));
                }
                if (CollectionUtils.isNotEmpty(privilegeCategories)) {
                    List<String> categories = new ArrayList<>();
                    for (PrivilegeCategory privilegeCategory : privilegeCategories) {
                        categories.add(privilegeCategory.name());
                    }
                    booleanBuilder.and(QScPrivilege.scPrivilege.category.in(categories));
                }


                List<Tuple> list = sqlQuery
                        .join(QScPrivilege.scPrivilege).on(QScPrivilege.scPrivilege.scResourceId.eq(QScResource.scResource.id))
                        .where(QScPrivilege.scPrivilege.name.in(privileges).and(booleanBuilder.getValue()))
                        .orderBy(QScResource.scResource.ordinal.asc())
                        .list(QScResource.scResource, QScPrivilege.scPrivilege);
                return BeanConvertUtils.convertDomainToVO(list, ScResource.class);
            }
        });
    }


}

